import type React from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import Toolbar from '../Toolbar';
import {
  type CoordinateSystemConfig,
  createDefaultPanState,
  createDefaultZoomState,
  drawCoordinateSystem,
  getMouseCoordinate,
  handleMouseDown,
  handleMouseLeave,
  handleMouseMove,
  handleMouseUp,
  handleWheelZoom,
  type PanState,
  resetZoom,
  toggleZoomMode,
  type ZoomState,
} from './coordinateLogic';
import styles from './index.module.less';

interface CoordinateSystemProps {
  width?: number;
  height?: number;
  unitSize?: number; // 每个单位对应的像素数
  minScale?: number; // 最小缩放限制
  maxScale?: number; // 最大缩放限制
}

const CoordinateSystem: React.FC<CoordinateSystemProps> = ({
  width = 800,
  height = 600,
  unitSize = 20,
  minScale = -Infinity,
  maxScale = Infinity,
}) => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [panState, setPanState] = useState<PanState>(() => {
    const defaultState = createDefaultPanState();
    console.log('Initializing panState:', defaultState);
    return defaultState;
  });

  const [zoomState, setZoomState] = useState<ZoomState>(() => {
    const defaultState = createDefaultZoomState(minScale, maxScale);
    console.log('Initializing zoomState:', defaultState);
    return defaultState;
  });

  const [mouseCoord, setMouseCoord] = useState<{ x: number; y: number }>({
    x: 0,
    y: 0,
  });

  // 绘制坐标系
  const drawCoordinateSystemCallback = useCallback(() => {
    const canvas = canvasRef.current;
    if (!canvas || !panState || !zoomState) return;

    const config: CoordinateSystemConfig = {
      width,
      height,
      unitSize,
    };

    drawCoordinateSystem({
      canvas,
      config,
      panState,
      zoomState,
    });
  }, [width, height, unitSize, panState, zoomState]);

  // 鼠标事件处理
  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const onMouseDown = (e: MouseEvent) => {
      setPanState((prev) =>
        prev ? handleMouseDown(e, prev) : createDefaultPanState(),
      );
    };

    const onMouseMove = (e: MouseEvent) => {
      const canvas = canvasRef.current;
      if (canvas && panState && zoomState) {
        const rect = canvas.getBoundingClientRect();
        const mouseX = e.clientX - rect.left;
        const mouseY = e.clientY - rect.top;

        const coord = getMouseCoordinate(
          mouseX,
          mouseY,
          canvas,
          panState,
          zoomState,
          unitSize,
        );
        setMouseCoord(coord);
      }

      setPanState((prev) =>
        prev ? handleMouseMove(e, prev) : createDefaultPanState(),
      );
    };

    const onMouseUp = () => {
      setPanState((prev) =>
        prev ? handleMouseUp(prev) : createDefaultPanState(),
      );
    };

    const onMouseLeave = () => {
      setPanState((prev) =>
        prev ? handleMouseLeave(prev) : createDefaultPanState(),
      );
    };

    const onWheel = (e: WheelEvent) => {
      e.preventDefault();
      setZoomState((prevZoom) => {
        if (!prevZoom || !panState) return prevZoom;
        const result = handleWheelZoom(e, prevZoom, canvas, panState);
        setPanState(result.panState);
        return result.zoomState;
      });
    };

    // 添加事件监听器
    canvas.addEventListener('mousedown', onMouseDown);
    canvas.addEventListener('mousemove', onMouseMove);
    canvas.addEventListener('mouseup', onMouseUp);
    canvas.addEventListener('mouseleave', onMouseLeave);
    canvas.addEventListener('wheel', onWheel, { passive: false });

    return () => {
      // 清理事件监听器
      canvas.removeEventListener('mousedown', onMouseDown);
      canvas.removeEventListener('mousemove', onMouseMove);
      canvas.removeEventListener('mouseup', onMouseUp);
      canvas.removeEventListener('mouseleave', onMouseLeave);
      canvas.removeEventListener('wheel', onWheel);
    };
  }, [panState, zoomState, unitSize]);

  // 当平移状态或参数变化时重新绘制
  useEffect(() => {
    drawCoordinateSystemCallback();
  }, [drawCoordinateSystemCallback]);

  const handleResetZoom = () => {
    setZoomState((prev) => (prev ? resetZoom(prev) : createDefaultZoomState()));
  };

  const handleToggleZoomMode = () => {
    setZoomState((prev) =>
      prev ? toggleZoomMode(prev) : createDefaultZoomState(),
    );
  };

  return (
    <div className={styles.container}>
      <canvas
        ref={canvasRef}
        className={`${styles.canvas} ${panState?.isPanning ? styles.panning : ''}`}
      />
      <Toolbar
        onResetZoom={handleResetZoom}
        onToggleZoomMode={handleToggleZoomMode}
        currentScale={zoomState?.scale || 1}
        zoomMode={zoomState?.zoomMode || 'mouse'}
        mouseCoord={mouseCoord}
      />
    </div>
  );
};

export default CoordinateSystem;
